home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 17 / CU Amiga Magazine's Super CD-ROM 17 (1997)(EMAP Images)(GB)[!][issue 1997-12].iso / CUCD / Programming / DiceSource / doc / REGARGS.DOC < prev    next >
Text File  |  1994-02-13  |  8KB  |  244 lines

  1.  
  2.  
  3. extensions/regargs                    extensions/regargs
  4. extensions/REGARGS                    extensions/REGARGS
  5.  
  6.               USING REGISTERIZED ARGUMENTS
  7.  
  8.     Using registerized arguments will make your code smaller and faster,
  9.     but there are some restrictions and various other things you must be
  10.     sure to do before you can use the feature reliably.
  11.  
  12.     RESTRICTIONS WITH 1.3
  13.  
  14.     No standard prototype headers exist for the Amiga includes under
  15.     1.3.  Since REGARGS depends on the programmer using the same
  16.     prototypes as were used to generate the regargs library, no
  17.     regargs library (would be amigasr.lib) exists for 1.3
  18.  
  19.     Under 2.0, the prototypes do exist in the directory
  20.     CLIB/#?_protos.h , and a 2.0 version of amiga.lib does
  21.     exist (AMIGASR20.LIB).
  22.  
  23.     Thus, under 1.3 you cannot use REGARGS for system calls, though
  24.     you can use it for all the functions within your program.  To
  25.     prevent DICE from attempting to make regargs system calls (if
  26.     this occurs you will get undefined symbol errors in link showing
  27.     symbols that begin with an '@'), you must either not prototype
  28.     the arguments to the system calls, or prototype them with
  29.     __stkargs.  Example:
  30.  
  31.         void *AllocMem();                           /*  OK  */
  32.         __stkargs void *AllocMem(long, long)        /*  OK  */
  33.  
  34.         void *AllocMem(long, long)                  /*  WRONG */
  35.  
  36.     The second method is the one of choise (using __stkargs) because it
  37.     allows you to do strict prototype checking (-proto option to DCC)
  38.     and mix non-registered amiga.lib calls with registered calls
  39.  
  40.     RESTRICTIONS IN AMIGASR20.LIB, (GENERAL)
  41.  
  42.     The registerized version of amiga.lib does not contain all
  43.     amiga.lib functions.  Of major import: CreateTask() and
  44.     DeleteTask() are missing.  The single precision FFP routines
  45.     do not exist either.
  46.  
  47.     PROTOTYPING IS MANDATORY
  48.  
  49.     You MUST supply prototypes for all procedure calls, this is how
  50.     DICE determines what registers to put things into.  The prototypes
  51.     must match the actual function declarations.
  52.  
  53.     When making amiga library calls, such as Open(), FindTask(),
  54.     OpenWindow(), etc..., you must include the appropriate amiga
  55.     prototype file in dinclude:amiga/clib/ .. for example,
  56.  
  57.         #include <clib/intuition_protos.h>
  58.  
  59.     It is STRONGLY SUGGESTED that you use the -proto option to DCC
  60.     to ensure all your calls have been prototyped.    For c.lib
  61.     functions the appropriate #includes must be made, such as
  62.     <stdio.h>, <stdlib.h>, <fcntl.h>, and <string.h>
  63.  
  64.     ANSI MAIN() ENTRY POINT
  65.  
  66.     main() MUST be declared in the following manner, even if you do not
  67.     use either argc and argv.  Be sure to either exit() out of main
  68.     or return() an exit value
  69.  
  70.         int
  71.         main(ac, av)
  72.         int ac;        /*    can specify short here */
  73.         char **av;
  74.         {
  75.  
  76.         return(0);
  77.         }
  78.  
  79.     WHAT GETS REGISTERIZED, FORMAL ENTRY POINTS
  80.  
  81.     DICE generates an @symbol entry point for registerized procedures,
  82.     a _symbol entry point for non-registerized procedures.
  83.  
  84.     * procedures taking no arguments are not registerized (nothing
  85.       to registerize)
  86.  
  87.     * unprototyped procedures are not registerized
  88.  
  89.     * currently, procedures with greater than 4 arguments will not
  90.       be registerized
  91.  
  92.     INDIRECT FUNCTION POINTERS
  93.  
  94.     DICE handles function pointers according to the -mr, -mR, -mRR
  95.     option specified:
  96.  
  97.     -mr
  98.         function pointers are assigned the unregistered entry point
  99.         for procedures only, all calls through function pointers
  100.         use stack based arguments.
  101.  
  102.         DICE generates both types of entry points for each procedure
  103.         definition.
  104.  
  105.     -mR
  106.         function pointers are assigned the unregistered entry point
  107.         for procedures only, all calls through function pointers
  108.         use stack based arguments.
  109.  
  110.         DICE generates only the registered (@) entry point for a
  111.         procedure definition.
  112.  
  113.     -mRR
  114.         function pointers are assigned the unregistered entry point
  115.         if they are not prototyped (see below), the registered entry
  116.         point if they are.    However, if the procedure was defined
  117.         with __stkargs, then the unregistered entry point will be
  118.         used.
  119.  
  120.         calls through function pointers use stack args for unprototyped
  121.         function pointers, reg-args for prototyped function pointers.
  122.  
  123.         WARNING:    Any procedure assigned to a function pointer must
  124.         be declared in the same manner as the function pointer.
  125.  
  126.     EXAMPLE, function table array:
  127.  
  128.         struct entry {
  129.         char *funcName;
  130.         void (*funcPtr)(char *);
  131.         } *En;
  132.  
  133.         extern void fubar(char *);
  134.         ...
  135.  
  136.  
  137.         En->funcPtr = fubar;
  138.         En->funcPtr("this is a test");
  139.  
  140.     Note how the function pointer in the entry structure is declared.
  141.     It is PROTOTYPED in of itself as taking a (char *).  Any procedure,
  142.     such as fubar, that you might assign to this variable MUST BE
  143.     DECLARED IN THE SAME MANNER.  In this case, it is:
  144.  
  145.         extern void fubar(char *);
  146.  
  147.     Which exactly matches the specification for the function pointer.
  148.     When you use the -mRR option matching the table with the functions
  149.     it is assigned with is IMPARATIVE.  If you make a mistake, at
  150.     best DICE will warn you with a failed link (looking for an entry
  151.     point that does not exist).  At worst it will not warn you and
  152.     the program will operate improperly.  It is suggested that you
  153.     use the -mr or -mR options until you get up to speed.
  154.  
  155.     FORCING STACK BASED PROCEDURES
  156.  
  157.     Here is an example of a prototype and its procedure definition
  158.     to force stack based arguments:
  159.  
  160.         extern __stkargs void fubar(char *);
  161.  
  162.         __stkargs void
  163.         fubar(char *ptr)
  164.         {
  165.         ...
  166.         }
  167.  
  168.     Note that BOTH THE PROTOTYPE AND THE PROCEDURE ITSELF MUST
  169.     specify the __stkargs flag.  Assigning any procedure qualified
  170.     with only __stkargs (rather than both __stkargs and __stkregs)
  171.     always assigns the stack based entry point rather than the
  172.     (possibly non-existant) register based entry point.
  173.  
  174.     Any call-back procedure you pass to the Amiga OS or any library
  175.     must be prototyped and defined like this because the library will
  176.     always call it back with stack based arguments unless otherwise
  177.     specified by the library.
  178.  
  179.     FORCING STACK BASED INDIRECT FUNCTION POINTERS
  180.  
  181.     Lets go back to that structure.. lets say you want any procedures
  182.     called through the indirect function pointer to be called using
  183.     stack based arguments.    You would then specify:
  184.  
  185.         struct entry {
  186.         char *funcName;
  187.         __stkargs void (*funcPtr)(char *);
  188.         } *En;
  189.  
  190.     But BE CAREFUL.  Any function assigned to this structure entry
  191.     must also be __stkargs:
  192.  
  193.         extern __stkargs void fubar(char *);    /*  RIGHT   */
  194.         extern void fubar(char *);              /*  WRONG   */
  195.  
  196.         ...
  197.  
  198.         En->funcPtr = fubar;
  199.  
  200.     If you do NOT match the argument type properly, DICE will
  201.     generate incorrect code.  Again, this is when you use the -mRR
  202.     option.  If you use only -mr or -mR (and specify __stkargs for
  203.     the procedures in question), this kind of problem will not
  204.     crop up.
  205.  
  206.     CALL-BACKS (C.LIB, AMIGA.LIB)
  207.  
  208.     C.LIB and AMIGA.LIB handle call-backs differently.  With C.LIB,
  209.     if you link without -m[r,R,RR] then everything uses stack based
  210.     arguments.  However, if you link with -mr, -mR, or -mRR then
  211.     CR.LIB is linked in instead of C.LIB, and any call-back functions
  212.     you supply to it (for example, qsort()) must use the registerized
  213.     entry point.
  214.  
  215.     Therefore, if you use C.LIB call-backs you cannot use -mr or -mR
  216.     ... you MUST use -mRR or not use registerization at all.  This is
  217.     because, if you remember, -mr and -mR always pass the
  218.     unregisterized entry point for anything but a direct call to the
  219.     routine (-mR exists to make porting code easier)
  220.  
  221.     AMIGA.LIB works the flip-side.    Since these are commodore-standard
  222.     routines any call-backs will be using stack-based arguments.  Thus,
  223.     any procedure you pass to an AMIGA.LIB routine must be declared
  224.     __stkargs.  This is a special case:
  225.  
  226.  
  227.         int ben(int (*)(int));
  228.  
  229.         __stkargs int fubar(int x)
  230.         {
  231.         ben(fubar);
  232.         }
  233.  
  234.     Even though ben() is fully prototyped to take a function pointer
  235.     that is fully prototyped, since fubar has been declared as a
  236.     stack-only routine, _fubar will be passed to ben instead of
  237.     @fubar.
  238.  
  239.     Thus, Amiga.Lib routines may be fully prototyped but as long as
  240.     you pass a stack-args only routine to them, the stack-args entry
  241.     point will be passed instead of the reg-args entry point.
  242.  
  243.  
  244.